/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-10     xu       the first version
 */
#include "amap_location_api.h"

#include "cJSON.h"
#include "gbk2utf8.h"
#include "http_api_utils.h"
#include "webclient.h"

#define DBG_TAG "loc.api"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <rtthread.h>

#define PUBLIC_IP_URL "http://pv.sohu.com/cityjson"
#define IP_RESPONSE_PREFIX "var returnCitySN ="

int wan_ip_address_get(ip_address_t* ip)
{
    char* response = RT_NULL;
    size_t resp_len = 0;

    if (ip == RT_NULL) {
        LOG_E("ip null!");
        return -1;
    }

    if (http_get(PUBLIC_IP_URL, &response, &resp_len) < 0) {
        // if (webclient_request(PUBLIC_IP_URL, RT_NULL, RT_NULL, 0, (void**)&response, &resp_len) < 0) {
        LOG_E("webclient send get request failed.");
        return -RT_ERROR;
    }
    LOG_D("Got response data: %d %d\n", resp_len, rt_strlen(response));

    if (rt_strncmp(response, IP_RESPONSE_PREFIX, rt_strlen(IP_RESPONSE_PREFIX)) == 0) {
        char* json = response + rt_strlen(IP_RESPONSE_PREFIX);
        if (json[resp_len - 1] == ';') {
            json[resp_len - 1] = '\0';
        }

        cJSON* root = cJSON_Parse(json);
        if (root) {
            cJSON* cip = cJSON_GetObjectItem(root, "cip");
            if (cip) {
                rt_strncpy(ip->ip, cip->valuestring, sizeof(ip->ip));
                LOG_D("Got IP: %s", ip->ip);
            }
            cJSON_Delete(root);
        }
    }

    if (response) {
        web_free(response);
    }
    return 0;
}

#define LOCATION_URL_FORMAT "http://restapi.amap.com/v3/ip?key=%s&ip=%s"
#define LOCATION_URL_BUFFER_MAX 128

amap_location_info_t amap_location_get()
{
    ip_address_t ip = {0};
    if (wan_ip_address_get(&ip) < 0) {
        LOG_E("get ip failed!");
        return RT_NULL;
    }

    char* url_buffer = rt_malloc(LOCATION_URL_BUFFER_MAX);
    if (url_buffer == RT_NULL) {
        LOG_E("alloc url buffer failed!");
        return RT_NULL;
    }
    rt_snprintf(url_buffer, LOCATION_URL_BUFFER_MAX, LOCATION_URL_FORMAT, APP_AMAP_API_KEY, ip.ip);
    LOG_D("prepare location request URL done!");

    char* response = RT_NULL;
    size_t resp_len = 0;
    if (http_get(url_buffer, &response, &resp_len) < 0) {
        // if (webclient_request(url_buffer, RT_NULL, RT_NULL, 0, (void**)&response, &resp_len) < 0) {
        rt_free(url_buffer);
        LOG_E("webclient send get request failed.");
        return RT_NULL;
    }
    rt_free(url_buffer);
    LOG_D("Got response data: %d", resp_len);

    amap_location_info_t loc_info = RT_NULL;
    if (resp_len > 0) {
        loc_info = rt_calloc(1, sizeof(struct location_info));
        if (loc_info == RT_NULL) {
            rt_free(url_buffer);
            LOG_E("alloc location info failed!");
            return RT_NULL;
        }

        cJSON* root = cJSON_Parse(response);
        copy_string_field(&loc_info->province, root, "province");
        copy_string_field(&loc_info->city, root, "city");
        copy_string_field(&loc_info->adcode, root, "adcode");
        copy_string_field(&loc_info->rectangle, root, "rectangle");
        cJSON_Delete(root);
    }

    if (response) {
        web_free(response);
    }
    return loc_info;
}

void amap_location_delete(amap_location_info_t loc)
{
    if (loc == RT_NULL) {
        LOG_E("loc null!");
        return;
    }

    SAFE_FREE(loc->province);
    SAFE_FREE(loc->city);
    SAFE_FREE(loc->adcode);
    SAFE_FREE(loc->rectangle);

    rt_free(loc);
}

static int ip_test(int argc, char* argv[])
{
    ip_address_t ip = {0};
    if (wan_ip_address_get(&ip) < 0) {
        LOG_E("get ip failed!");
        return -1;
    }
    return 0;
}
MSH_CMD_EXPORT(ip_test, Public ip API test);

static int loc_test(int argc, char* argv[])
{
    amap_location_info_t info = amap_location_get();
    RT_ASSERT(info);
    amap_location_delete(info);
    return 0;
}
MSH_CMD_EXPORT(loc_test, Location API test);
